{
 "cells": [
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## Mnist分类任务:\n",
    "-网络基本构建与训练方法，常用函数解析\n",
    "- torch.nn.functional模块\n",
    "- nn.Module模块"
   ],
   "id": "fd1ed51e5e123a84"
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 读取MNIST数据集",
   "id": "c49e2fb515e9f659"
  },
  {
   "metadata": {},
   "cell_type": "code",
   "source": [
    "%matplotlib inline\n",
    "from pathlib import Path\n",
    "import requests\n",
    "DATA_PATH = Path('data')\n",
    "PATH = DATA_PATH / \"mnist\"\n",
    "PATH.mkdir(parents=True,exist_ok=True)\n",
    "\n",
    "URL = \"http://deeplearning.net/data/mnist/\"\n",
    "FILE_NAME = \"mnist.pkl.gz\"\n",
    "\n",
    "if not (PATH / FILE_NAME).exists():\n",
    "    content = requests.get(URL + FILE_NAME).content\n",
    "    (PATH / FILE_NAME).open(\"wb\").write(content)"
   ],
   "id": "a554d6a84b410fce",
   "outputs": [],
   "execution_count": null
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": [
    "import pickle\n",
    "import gzip\n",
    "with gzip.open((PATH / FILE_NAME), \"rb\") as f:\n",
    "    ((x_train, y_train), (x_test, y_test)) = pickle.load(f, encoding=\"latin-1\")\n",
    "    "
   ],
   "id": "4df0d7f9eda1836a"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-22T12:16:23.100989Z",
     "start_time": "2025-02-22T12:16:22.463476Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import torch\n",
    "from torch import nn, optim\n",
    "from torch.utils.data import DataLoader\n",
    "from torchvision import datasets, transforms\n",
    "\n",
    "data_tf = transforms.Compose(\n",
    "    [transforms.ToTensor(),\n",
    "     transforms.Normalize([0.5], [0.5])])\n",
    "\n",
    "batch_size = 32\n",
    "# 读取测试数据，train=True读取训练数据；train=False读取测试数据\n",
    "train_dataset = datasets.MNIST(root='./data', train=True, transform=data_tf, download=True)\n",
    "test_dataset = datasets.MNIST(root='./data', train=False, transform=data_tf)\n",
    "test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)\n",
    "train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\n",
    "\n",
    "examples = enumerate(test_loader) #img&label\n",
    "batch_idx, (imgs, labels) = next(examples) #读取数据,batch_idx从0开始\n",
    "\n",
    "print(labels) #读取标签数据\n",
    "print(labels.shape) #torch.Size([32])，因为batch_size为32\n",
    "\n",
    "#-------------------------------数据显示--------------------------------------------\n",
    "#显示6张图片\n",
    "import matplotlib.pyplot as plt\n",
    "fig = plt.figure()\n",
    "for i in range(6):\n",
    "  plt.subplot(2,3,i+1)\n",
    "  plt.tight_layout()\n",
    "  plt.imshow(imgs[i][0], cmap='gray', interpolation='none')#子显示\n",
    "  plt.title(\"Ground Truth: {}\".format(labels[i])) #显示title\n",
    "  plt.xticks([])\n",
    "  plt.yticks([])\n",
    "\n",
    "plt.show()\n"
   ],
   "id": "759aefd9a6997c2d",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([7, 2, 1, 0, 4, 1, 4, 9, 5, 9, 0, 6, 9, 0, 1, 5, 9, 7, 3, 4, 9, 6, 6, 5,\n",
      "        4, 0, 7, 4, 0, 1, 3, 1])\n",
      "torch.Size([32])\n"
     ]
    },
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 6 Axes>"
      ],
      "image/png": "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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 12
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## torch.nn.functional 很多层和函数在这里都会见到\n",
    "- nn.Module，其他情况nn.functional相对更简单一些\n",
    "- torch.nn.functional中有很多功能，后续会常用的，那什么时候使用nn.Module，什么时候使用nn.funcional呢?一般情况下，如果模型有可学习的参数，最好用"
   ],
   "id": "73a89b608fa0e8f0"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-22T11:53:07.656454Z",
     "start_time": "2025-02-22T11:53:07.651423Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import torch.nn.functional as F\n",
    "loss_fn = F.cross_entropy\n"
   ],
   "id": "25a1f59e174c222a",
   "outputs": [],
   "execution_count": 7
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "## 创建一个model来更简化代码\n",
    "- 必须继承nn.Module且在其构造函数中需调用nn.Module的构造函数无需写反向传播函数，m.Module能够利用autograd自动实现反向传播。\n",
    "- Module中的可学习参数可以通过named parameters()或者parameters()返回迭代器"
   ],
   "id": "80b77ee1edea4d27"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-22T12:25:20.972612Z",
     "start_time": "2025-02-22T12:25:20.960733Z"
    }
   },
   "cell_type": "code",
   "source": [
    "class Net(nn.Module):\n",
    "    def __init__(self):\n",
    "        super(Net, self).__init__()\n",
    "        self.hidden1 = nn.Linear(784, 256)\n",
    "        self.hidden2 = nn.Linear(256, 128)\n",
    "        self.out = nn.Linear(128, 10)\n",
    "    def forward(self, x):\n",
    "        x = x.view(x.size(0),-1)\n",
    "        x = F.relu(self.hidden1(x))\n",
    "        x = F.relu(self.hidden2(x))\n",
    "        x = self.out(x)\n",
    "        return x\n",
    "model = Net()\n",
    "model"
   ],
   "id": "10d5c01f914bd9dd",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "Net(\n",
       "  (hidden1): Linear(in_features=784, out_features=256, bias=True)\n",
       "  (hidden2): Linear(in_features=256, out_features=128, bias=True)\n",
       "  (out): Linear(in_features=128, out_features=10, bias=True)\n",
       ")"
      ]
     },
     "execution_count": 25,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 25
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": "## 打印参数值",
   "id": "6731077644e82b70"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-22T12:00:10.384643Z",
     "start_time": "2025-02-22T12:00:10.379604Z"
    }
   },
   "cell_type": "code",
   "source": [
    "for name, param in model.named_parameters():\n",
    "    print(name, param.size())"
   ],
   "id": "7dcc4bbc206fbdfc",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "hidden1.weight torch.Size([256, 784])\n",
      "hidden1.bias torch.Size([256])\n",
      "hidden2.weight torch.Size([128, 256])\n",
      "hidden2.bias torch.Size([128])\n",
      "out.weight torch.Size([10, 128])\n",
      "out.bias torch.Size([10])\n"
     ]
    }
   ],
   "execution_count": 11
  },
  {
   "metadata": {},
   "cell_type": "markdown",
   "source": [
    "- 一般在训练模型时加上model.train()，这样会正常使用Batch Normalization和 Dropout\n",
    "- 测试的时候一般选择model.eval()，这样就不会使用Batch Normalization和 Dropout"
   ],
   "id": "2598fdfcac9e8f15"
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-22T13:02:09.549981Z",
     "start_time": "2025-02-22T13:02:09.542016Z"
    }
   },
   "cell_type": "code",
   "source": [
    "import numpy as np\n",
    "def loss_batch(model, loss_fn,optimizer, xb, yb):\n",
    "    loss = loss_fn(model(xb), yb)\n",
    "    if optimizer is not None:\n",
    "        loss.backward()\n",
    "        optimizer.step()\n",
    "        optimizer.zero_grad()\n",
    "    return loss.item(), len(xb)\n",
    "\n",
    "def fit(epochs, model, loss_fn, optimizer, train_dl, valid_dl):\n",
    "    losses = []\n",
    "    for epoch in range(epochs):\n",
    "        model.train()\n",
    "        for xb, yb in train_dl:\n",
    "            loss_batch(model, loss_fn, optimizer, xb, yb)\n",
    "        model.eval()\n",
    "        with torch.no_grad():\n",
    "            arr = [loss_batch(model, loss_fn, None, xb, yb) for x, y in valid_dl]\n",
    "            losses, nums = zip(*arr)\n",
    "        val_loss = np.sum(np.multiply(losses, nums)) / np.sum(nums)\n",
    "        print(\"当前epoch：{}, 验证集损失：{}\".format(epoch + 1, val_loss))\n",
    "    losses.append(val_loss)  \n",
    "    return losses"
   ],
   "id": "4b7733b40e2f0c23",
   "outputs": [],
   "execution_count": 74
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-22T13:01:13.443586Z",
     "start_time": "2025-02-22T12:57:22.437637Z"
    }
   },
   "cell_type": "code",
   "source": [
    "data_tf = transforms.Compose(\n",
    "    [transforms.ToTensor(),\n",
    "     transforms.Normalize([0.5], [0.5])])\n",
    "\n",
    "batch_size = 32\n",
    "# 读取测试数据，train=True读取训练数据；train=False读取测试数据\n",
    "train_dataset = datasets.MNIST(root='./data', train=True, transform=data_tf, download=True)\n",
    "test_dataset = datasets.MNIST(root='./data', train=False, transform=data_tf, download=True)\n",
    "test_loader = DataLoader(test_dataset, batch_size=batch_size, shuffle=False)\n",
    "train_loader = DataLoader(train_dataset, batch_size=batch_size, shuffle=True)\n",
    "loss_fn = torch.nn.CrossEntropyLoss()\n",
    "optimizer = optim.Adam(model.parameters(), lr=0.001)\n",
    "fit(10, model, loss_fn, optimizer, train_loader, test_loader)"
   ],
   "id": "1dda59cdee4c4c1a",
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "当前epoch：1, 验证集损失：0.007949106395244598\n",
      "当前epoch：2, 验证集损失：0.0002022569824475795\n",
      "当前epoch：3, 验证集损失：0.0009654506575316191\n",
      "当前epoch：4, 验证集损失：0.020014403387904167\n",
      "当前epoch：5, 验证集损失：0.00013531354488804936\n",
      "当前epoch：6, 验证集损失：1.794611307559535e-05\n",
      "当前epoch：7, 验证集损失：0.0010523450328037143\n",
      "当前epoch：8, 验证集损失：0.00186221394687891\n",
      "当前epoch：9, 验证集损失：0.007782862987369299\n",
      "当前epoch：10, 验证集损失：0.002043377608060837\n"
     ]
    }
   ],
   "execution_count": 73
  },
  {
   "metadata": {},
   "cell_type": "code",
   "outputs": [],
   "execution_count": null,
   "source": "",
   "id": "6a836d2c85e3ac96"
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 2
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython2",
   "version": "2.7.6"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
